from Quoridor_game import QuoridorAction, WHITE, BLACK, TIE, QuoridorState, DIRECTIONS
from game_runner import GameRunner
from game_agent import GameAgent
from alpha_beta import AlphaBetaSearch
import random
from smart_agent import SmartAgent
from time import clock

PAUSES = False

class DummyAgent(GameAgent):
    def move(self, game_state):
        actions = game_state.getSuccessors().keys()        
        actionNdx = random.randrange(len(actions))
        action = actions[actionNdx]
        
        if (PAUSES):
            raw_input('enter to continue...')
        
        return action
    
    def setup(self, player, game_state, turn_time_limit, setup_time_limit):
        random.seed()
        
        print 'Setup for Dummy player: ' + player

class AlphaBetaAgent(GameAgent):
    def __init__(self, depth):
        self.depth = depth

    def move(self, game_state):
        action = self.alphaBeta.search(game_state)
        
        if (PAUSES):
            raw_input('enter to continue...')
        
        return action
    
    def setup(self, player, game_state, turn_time_limit, setup_time_limit):
        self.player = player
        u = lambda state: self.utility(state)
        self.alphaBeta = AlphaBetaSearch(self.player, self.depth, u)

    #this is in-fact the heuristic value. In this case the heuristic is not very helpful, play with it and see why... 
    def utility(self, state):
        winner = state.getWinner()
        if winner is None:
            whiteDistance = 0
            for posW in state.locationsW:
                if posW != None: 
                    whiteDistance += (state.brdSize - 1 - posW[0])
                    whiteDistance += (posW[1] / 10.0)
            
            blackDistance = 0
            for posB in state.locationsB:
                if posB != None: 
                    blackDistance += posB[0]
                    blackDistance += (posB[1] / 10.0) 
            
            utilityValW = blackDistance - whiteDistance
            if self.player == WHITE:
                return utilityValW
            else:
                return -utilityValW            
            
        elif winner == self.player:
            return 100000
        elif winner == TIE:
            return 0
        else:
            return -100000

class InteractiveAgent(GameAgent):
    def move(self, game_state):
        ok = False        
        while not ok:
            print self.player + ' player\'s turn'
            print 'to move a piece: "M pieceNdx N/S/W/E" \n'
            print 'to place a vertical/horizontal wall: "WV/WH majorNdx minorNdx" \n'
            inp = raw_input ('your selection: ')
            actionParams = inp.split()
     
            try:
                if len(actionParams) != 3 or actionParams[0] not in QuoridorAction.LegalTypes:
                    raise Exception()
                type = actionParams[0]            
                if (type == 'M'):
                    dir = actionParams[2]                    
                    pieceNdx = int(actionParams[1])
                    if ((dir not in DIRECTIONS) or (pieceNdx not in xrange(game_state.numPieces))):                        
                        raise Exception()                    
                    info = [pieceNdx, dir]
                else:
                    info = [int(actionParams[1]),int(actionParams[2])]
                action = QuoridorAction(type, info)
            except:
                print 'Bad format\n\n'
                continue            
            ok = True

        return action           

    def setup(self, player, game_state, turn_time_limit, setup_time_limit):        
        self.player = player
        print 'Setup for Interactive player: ' + player
        
agents = {}
agents[WHITE] = AlphaBetaAgent(1)
agents[BLACK] = SmartAgent()


state = QuoridorState(2)
print 'Initial state: \n'
print str(state) + '\n' 
winner = GameRunner(state, agents, 15, 1).run()
l = agents[BLACK].alphaBeta.bf_counter
print 'Avrage -',str(sum(l)/len(l))
print 'Winner:', winner